package com.pm.common.utils;

import com.alibaba.fastjson2.JSONObject;
import com.pm.common.config.ParamConfig;
import com.pm.common.constant.ProjectConstants;
import com.pm.common.core.domain.entity.Attachment;
import com.pm.common.core.domain.entity.Review;
import com.pm.common.exception.UtilException;
import okhttp3.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.UUID;


/**
 * OA集成工具类
 */
@Component
public class OaUtils {
    @Resource
    private ParamConfig paramConfig;

    @Resource
    private RestTemplate restTemplate;


    /**
     *
     * 发起OA流程（okhttp3）
     * @param docSubject OA表单，OA提供
     //* @param fdTemplateId OA流程id OA提供 String fdTemplateId,
     * @param createSN  发起人
     * @param formPar   表单参数
     * @param futureNodeId 审批人参数
     * @param file  文件列表
     * @return 返回OAid
     * @throws IOException
     */
    public String addReview(String docSubject,String createSN,
                            String formPar, JSONObject futureNodeId, String file)
            throws Exception {
        //账号
        String name = paramConfig.getOaLoginName();
        //密码
        String passWord = paramConfig.getOaPassWord();
        //流程id
        String fdTemplateId = paramConfig.getWaiveProcessId();
        //请求流程接口url
        String url = paramConfig.getOaUrl();

        OkHttpClient client = new OkHttpClient().newBuilder()
                .authenticator(new Authenticator() {
                    @Override
                    public Request authenticate(Route route, Response response) throws IOException {
                        String credential = Credentials.basic(name, passWord);
                        return response.request().newBuilder()
                                .header("Authorization", credential)
                                .build();
                    }
                })
                .build();

        //okhttp3.MediaType mediaType = okhttp3.MediaType.parse("application/json; charset=utf-8");
        MultipartBody.Builder builder=new MultipartBody.Builder().setType(MultipartBody.FORM);

        //表单参数
        builder.addFormDataPart("docSubject", docSubject);
        builder.addFormDataPart("fdTemplateId", fdTemplateId);

        String creater="{\"LoginName\":\""+createSN+"\"}";
        builder.addFormDataPart("docCreator", creater);
        builder.addFormDataPart("docStatus", "20");
        builder.addFormDataPart("formValues",formPar);
        //builder.addFormDataPart("attachmentUrlValues",file);//附件
        builder.addFormDataPart("fdNumber",UUID.randomUUID().toString());
        builder.addFormDataPart("fdSource","BL");

        RequestBody body=builder.build();

        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
                .build();

        //执行
        Response response = client.newCall(request).execute();

        //返回值
        String result = response.body().string();
        JSONObject resp= JSONObject.parseObject(result);
        Boolean success = resp.getBoolean("success");
        if(success){
            return resp.get("data").toString();
        }else {
            throw new Exception(result);
        }
    }

    /**
     * 推送OA系统创建流程方法(restTemplate)
     * @param createSN  发起人工号
     * @param formPar  表单参数
     * @param futureNodeId 审批人参数
     * @param file  附件文件列表
     * @return 返回OAid
     */
    public String addReview2(String createSN,
                             String formPar, JSONObject futureNodeId, String file) throws Exception {
        //获取请求所需的参数
        //账号
        String name = paramConfig.getOaLoginName();
        //密码
        String passWord = paramConfig.getOaPassWord();
        //流程id
        String fdTemplateId = paramConfig.getWaiveProcessId();

        String docSubject = paramConfig.getWaiveProcessTemplate();
        //推送接口
        String url = paramConfig.getOaUrl();

        //封装参数
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        String creater="{\"LoginName\":\""+createSN+"\"}";//创建人
        params.add("docSubject",docSubject);//流程主题
        params.add("fdTemplateId", fdTemplateId);//流程id
        params.add("docCreator", creater);//创建人
        params.add("docStatus", "20");//流程状态
        params.add("formValues",formPar);//表单参数
//        params.add("attachmentUrlValues",file);//附件
        params.add("fdNumber",UUID.randomUUID().toString());
        params.add("fdSource","BL");//数据源
        //封装设置请求头参数
        HttpHeaders headers = new HttpHeaders();
        String authentication = name+":"+passWord;
        String credential = Base64.getEncoder().encodeToString(authentication.getBytes());
        //设置登录权限认证
//        headers.set("Authorization","Basic"+credential);
        headers.set("Authorization",credential);
        //表单的形式请求
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //请求参数与请求头封装
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        //发送请求
        JSONObject resp = restTemplate.postForObject(url, requestEntity, JSONObject.class);
        if(resp.getBoolean("success")){
            return resp.get("data").toString();
        }else {
            throw new UtilException(resp.toString());
        }

    }


    /**
     * 推送OA生成流程接口
     * @param review
     * @return
     */
    public JSONObject addReview3(Review review){
        JSONObject param = JSONObject.from(review);

        //处理附件
        if(!CollectionUtils.isEmpty(review.getAttachmentForms())){
            List<JSONObject> files = new ArrayList<>();
            List<Attachment> attachmentList = review.getAttachmentForms();
            String fdKey = null;
            for(int i=0;i<attachmentList.size();i++){
                Attachment attachment = attachmentList.get(i);
                JSONObject obj = new JSONObject();
                fdKey = attachment.getFdKey();
                obj.put("name",attachment.getFdFileName());
                obj.put("url",paramConfig.getFileServer()+ File.separator+attachment.getPath());
                files.add(obj);
            }

            JSONObject attachmentUrlValues = new JSONObject();
            attachmentUrlValues.put(fdKey,files);
            param.put("attachmentUrlValues",attachmentUrlValues);

        }
        param.remove("attachmentForms");
        JSONObject osRes = restTemplate.postForObject(paramConfig.getOaAddr()+ ProjectConstants.EKP_ADD_REVIEW,param,JSONObject.class);
        return osRes;
    }


    /**
     * 推送OA生成流程接口
     * @param review
     * @return
     */
    public JSONObject updateReview(Review review){
        JSONObject param = JSONObject.from(review);

        //处理附件
        if(!CollectionUtils.isEmpty(review.getAttachmentForms())){
            List<JSONObject> files = new ArrayList<>();
            List<Attachment> attachmentList = review.getAttachmentForms();
            String fdKey = null;
            for(int i=0;i<attachmentList.size();i++){
                Attachment attachment = attachmentList.get(i);
                JSONObject obj = new JSONObject();
                fdKey = attachment.getFdKey();
                obj.put("name",attachment.getFdFileName());
                obj.put("url",paramConfig.getFileServer()+ File.separator+attachment.getPath());
                files.add(obj);
            }

            JSONObject attachmentUrlValues = new JSONObject();
            attachmentUrlValues.put(fdKey,files);
            param.put("attachmentUrlValues",attachmentUrlValues);

        }
        param.remove("attachmentForms");
        JSONObject osRes = restTemplate.postForObject(paramConfig.getOaAddr()+ ProjectConstants.EKP_UPDATE_REVIEW,param,JSONObject.class);
        return osRes;
    }

}
